package com.cnbot.camera.utils;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextPaint;
import android.util.Base64;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author wzz
 */
public class BitmapUtils {
    public BitmapUtils() {
    }

    public static Bitmap getFitSampleBitmap(String imagePath, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        BitmapFactory.decodeFile(imagePath, options);
        options.inSampleSize = getFitInSampleSize(width, height, options);
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
        if (bitmap != null) {
            bitmap = getSmallImage(bitmap, width, height, true);
            int bitmapDegree = getBitmapDegree(imagePath);
            bitmap = roateBitmap(bitmap, (float)bitmapDegree, true);
        }

        return bitmap;
    }

    public static Bitmap getOriginBitmap(String imagePath) {
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
        if (bitmap != null) {
            int bitmapDegree = getBitmapDegree(imagePath);
            bitmap = roateBitmap(bitmap, (float)bitmapDegree, true);
        }

        return bitmap;
    }

    public static Bitmap getSmallImage(Bitmap bitmap, int mWidth, int mHight, boolean isRecycle) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        float scaleH = (float)mHight / (float)h;
        float scaleW = (float)mWidth / (float)w;
        Matrix matrix = new Matrix();
        float min = Math.min(scaleH, scaleW);
        if (min >= 1.0F) {
            return bitmap;
        } else {
            matrix.postScale(min, min);
            return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
        }
    }

    public static int getFitInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options options) {
        int w = options.outWidth;
        int h = options.outHeight;
        int zoomRatio = 1;
        if (w > h && w > reqWidth) {
            zoomRatio = w / reqWidth;
        } else if (w < h && h > reqHeight) {
            zoomRatio = h / reqHeight;
        }

        return zoomRatio;
    }

    public static Bitmap createBitmap(int w, int h) {
        return Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    }

    public static Bitmap createBitmapByMatrix(Bitmap source, Matrix m, boolean filter, boolean isRecycle) {
        Bitmap result = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), m, filter);
        if (isRecycle && result != source) {
            recycleBitmap(source);
        }

        return result;
    }

    public static String saveBitmap(Context context, Bitmap b, String name) {
        return saveBitmap(context, b, name, Bitmap.CompressFormat.JPEG);
    }

    public static String saveBitmap(Context context, Bitmap b, String name, Bitmap.CompressFormat format) {
        File file = new File(name);
        File photoFile = savePhotoToSDCard(b, file.getParent(), file.getName(), format);

        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getParent(), file.getName(), null);
        } catch (FileNotFoundException var8) {
            var8.printStackTrace();
        }

        Intent intent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
        Uri uri = Uri.fromFile(photoFile);
        intent.setData(uri);
        context.sendBroadcast(intent);

        assert photoFile != null;

        return photoFile.getAbsolutePath();
    }

    public static File savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName) {
        return savePhotoToSDCard(photoBitmap, path, photoName, Bitmap.CompressFormat.JPEG);
    }

    private static File savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName, Bitmap.CompressFormat format) {
        if (checkSDCardAvailable()) {
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            File photoFile = new File(path, photoName);
            FileOutputStream fileOutputStream = null;

            File var7;
            try {
                fileOutputStream = new FileOutputStream(photoFile);
                if (photoBitmap.compress(format, 100, fileOutputStream)) {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }

                var7 = photoFile;
            } catch (FileNotFoundException var19) {
                photoFile.delete();
                var19.printStackTrace();
                return null;
            } catch (IOException var20) {
                photoFile.delete();
                var20.printStackTrace();
                return null;
            } finally {
                try {
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                } catch (IOException var18) {
                    var18.printStackTrace();
                }

            }

            return var7;
        } else {
            return null;
        }
    }

    public static boolean checkSDCardAvailable() {
        return "mounted".equals(Environment.getExternalStorageState());
    }

    public static Bitmap getScaleBitmap(Bitmap bitmap, float rate, boolean isRecycle) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(rate, rate);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap getFilpBitmap(Bitmap bitmap, boolean isRecycle) {
        Matrix matrix = new Matrix();
        matrix.postScale(-1.0F, 1.0F);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap getFilpBitmap(Bitmap bitmap, float angle, boolean isRecycle) {
        Matrix matrix = new Matrix();
        matrix.postScale(-1.0F, 1.0F);
        matrix.postRotate(angle);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap getTBFilpBitmap(Bitmap bitmap, float mAngle, boolean isRecycle) {
        Matrix matrix = new Matrix();
        matrix.postScale(1.0F, -1.0F);
        matrix.postRotate(mAngle);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap roateBitmap(Bitmap currentSelBitmap, float angle, boolean isRecycle) {
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        return createBitmapByMatrix(currentSelBitmap, matrix, false, isRecycle);
    }

    public static Bitmap getSmallBitmapByX(Bitmap bitmap, int mWidth, boolean isRecycle) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scale2 = (float)mWidth / (float)w;
        matrix.postScale(scale2, scale2);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap getSmallBitmapByY(Bitmap bitmap, int mHight, boolean isRecycle) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scale2 = (float)mHight / (float)h;
        matrix.postScale(scale2, scale2);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap getSmallBitmapByXY(Bitmap bitmap, int mWidth, int mHight, boolean isRecycle) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        float scaleH = (float)mHight / (float)h;
        float scaleW = (float)mWidth / (float)w;
        Matrix matrix = new Matrix();
        float min = Math.min(scaleH, scaleW);
        matrix.postScale(min, min);
        return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
    }

    public static Bitmap adjustViewAndBitmap(Bitmap bmp, View multipleLayersView, boolean isRecycle) {
        ViewGroup.LayoutParams layoutParams = multipleLayersView.getLayoutParams();
        int width = multipleLayersView.getMeasuredWidth();
        int height = multipleLayersView.getMeasuredHeight();
        int bitmapW = bmp.getWidth();
        int bitmapH = bmp.getHeight();
        float f1 = (float)width / (float)bitmapW;
        float f2 = (float)height / (float)bitmapH;
        Bitmap result;
        if (f2 > f1) {
            result = getSmallBitmapByX(bmp, width, isRecycle);
            layoutParams.height = result.getHeight();
            layoutParams.width = result.getWidth();
        } else {
            result = getSmallBitmapByY(bmp, height, isRecycle);
            layoutParams.height = result.getHeight();
            layoutParams.width = result.getWidth();
        }

        multipleLayersView.setLayoutParams(layoutParams);
        return result;
    }

    public static Bitmap createTxtBitmap(String str, Typeface font, int color) {
        TextPaint textPaint = new TextPaint();
        textPaint.setColor(color);
        textPaint.setTypeface(font);
        textPaint.setTextSize(300.0F);
        textPaint.setTextAlign(Paint.Align.LEFT);
        textPaint.setFakeBoldText(true);
        Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
        String[] split = str.split("\n");
        int maxIndex = 0;

        int i;
        for(i = 0; i < split.length; ++i) {
            if (split[maxIndex].length() < split[i].length()) {
                maxIndex = i;
            }
        }

        i = (int)textPaint.measureText(split[maxIndex]);
        int imageHeight = fontMetrics.descent + Math.abs(fontMetrics.ascent);
        int baseLine = 0 - fontMetrics.ascent;
        Bitmap bmp = Bitmap.createBitmap(i, imageHeight * split.length, Bitmap.Config.ARGB_8888);
        Canvas canvasTemp = new Canvas(bmp);
        canvasTemp.drawColor(0);
        if ("".equals(str)) {
            return bmp;
        } else {
            for(int ii = 0; ii < split.length; ++ii) {
                canvasTemp.drawText(split[ii], 0.0F, (float)(imageHeight * ii + baseLine), textPaint);
            }

            return bmp;
        }
    }

    public static Bitmap getWaterMask(Bitmap bitmap, Bitmap maskBitmap, boolean recycle) {
        Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvasTemp = new Canvas(bmp);
        canvasTemp.drawColor(0);
        int pading = (int)((double)bitmap.getWidth() * 0.025D);
        int newWidth = bitmap.getWidth() / 8;
        float rate = (float)newWidth / (float)maskBitmap.getWidth();
        int left = bitmap.getWidth() - newWidth - pading;
        int right = bitmap.getWidth() - pading;
        int top = bitmap.getHeight() - (int)((float)maskBitmap.getHeight() * rate) - pading;
        int bottom = bitmap.getHeight() - pading;
        canvasTemp.setDrawFilter(new PaintFlagsDrawFilter(0, 3));
        canvasTemp.drawBitmap(bitmap, 0.0F, 0.0F, null);
        canvasTemp.drawBitmap(maskBitmap, new Rect(0, 0, maskBitmap.getWidth(), maskBitmap.getHeight()), new Rect(left, top, right, bottom), null);
        if (recycle) {
            recycleBitmap(bitmap);
        }

        return bmp;
    }

    public static void recycleBitmap(Bitmap bitmap) {
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
        }

    }

    public static int getBitmapDegree(String path) {
        short degree = 0;

        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt("Orientation", 1);
            switch(orientation) {
                case 3:
                    degree = 180;
                    break;
                case 6:
                    degree = 90;
                    break;
                case 8:
                    degree = 270;
                    break;
                default:break;
            }
        } catch (IOException var4) {
            var4.printStackTrace();
        }

        return degree;
    }

    public static int[] getBitmapOffset(ImageView imageView, boolean includeLayout) {
        int[] offset = new int[2];
        float[] values = new float[9];
        Matrix matrix = imageView.getImageMatrix();
        matrix.getValues(values);
        offset[0] = (int)values[2];
        offset[1] = (int)values[5];
        if (includeLayout) {
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)imageView.getLayoutParams();
            int paddingTop = imageView.getPaddingTop();
            int paddingLeft = imageView.getPaddingLeft();
            offset[0] += paddingLeft + params.leftMargin;
            offset[1] += paddingTop + params.topMargin;
        }

        return offset;
    }

    public static String bitmapToBase64(Bitmap bitmap) {
        String result = null;
        ByteArrayOutputStream baos = null;

        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                baos.flush();
                baos.close();
                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, 0);
            }
        } catch (IOException var12) {
            var12.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException var11) {
                var11.printStackTrace();
            }

        }

        return result;
    }

    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, 0);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    private static boolean colorEquals(int color1, int color2) {
        return color1 == color2;
    }

    private static int mix(int crBack, int crForeground) {
        int rBack = Color.red(crBack);
        int gBack = Color.green(crBack);
        int bBack = Color.blue(crBack);
        int aForeground = Color.alpha(crForeground);
        int rForeground = Color.red(crForeground);
        int gForeground = Color.green(crForeground);
        int bForeground = Color.blue(crForeground);
        return Color.rgb((int)((float)rForeground * ((float)aForeground / 255.0F) + (float)rBack * (1.0F - (float)aForeground / 255.0F)), (int)((float)gForeground * ((float)aForeground / 255.0F) + (float)gBack * (1.0F - (float)aForeground / 255.0F)), (int)((float)bForeground * ((float)aForeground / 255.0F) + (float)bBack * (1.0F - (float)aForeground / 255.0F)));
    }

    public static Point getPathBitmapSize(String path) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        return new Point(options.outWidth, options.outHeight);
    }

    public static void compare2bitmap() {
        Bitmap bmp1 = BitmapFactory.decodeFile("/sdcard/compare1.jpg");
        Bitmap bmp2 = BitmapFactory.decodeFile("/sdcard/compare2.jpg");
        if (bmp1.getWidth() == bmp2.getWidth() && bmp1.getHeight() == bmp2.getHeight()) {
            Bitmap result1 = createBitmap(bmp1.getWidth(), bmp1.getHeight());

            for(int i = 0; i < bmp1.getWidth(); ++i) {
                for(int j = 0; j < bmp1.getHeight(); ++j) {
                    int color1 = bmp1.getPixel(i, j);
                    int color2 = bmp2.getPixel(i, j);
                    if (colorEquals(color1, color2)) {
                        result1.setPixel(i, j, color1);
                    } else {
                        result1.setPixel(i, j, mix(color1, Color.argb(128, 255, 0, 0)));
                    }
                }
            }

            savePhotoToSDCard(bmp1, "/sdcard", "test0.jpg");
            savePhotoToSDCard(bmp2, "/sdcard", "test1.jpg");
            savePhotoToSDCard(result1, "/sdcard", "test2.jpg");
        }

    }


    public static Bitmap loadBitmapFromView(View view) {
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bm = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        return bm;
    }
}
